MySQL: O Guia Definitivo
Dados são o novo petróleo, e o MySQL é o reservatório. Domine a linguagem SQL, a modelagem relacional e a arquitetura que sustenta a Web.
1. Introdução: A Origem do Golfinho
O MySQL foi criado na Suécia em 1995 por Michael "Monty" Widenius, David Axmark e Allan Larsson. Um fato curioso: o "My" no nome não significa "Meu" em inglês; é o nome da filha de Monty, que se chama "My".
Originalmente criado para ser um banco de dados leve para aplicações pessoais, ele explodiu em popularidade com a ascensão da Web 2.0. Hoje, pertence à Oracle, mas mantém sua versão Open Source (Community Edition) que é o padrão de mercado.
Por que ele existe? (A Necessidade)
Imagine guardar os dados de 1 milhão de usuários em arquivos de texto (.txt). Seria impossível buscar informações rapidamente ou garantir que dois usuários não editassem o mesmo arquivo ao mesmo tempo.
O MySQL existe para resolver dois problemas fundamentais da computação:
- Persistência Estruturada: Salvar dados de forma organizada (Tabelas, Linhas, Colunas).
- Integridade (ACID): Garantir que uma transação bancária não desapareça no meio do caminho se a luz acabar.
2. Arquitetura: O Motor Sob o Capô
O MySQL funciona no modelo Cliente-Servidor. Você (o cliente) envia um comando SQL, e o servidor processa e devolve o resultado. Mas a mágica acontece nos Storage Engines.
-
SQL Interface: Recebe seu comando (
SELECT * FROM...). - Parser & Optimizer: Analisa se o comando é válido e decide a forma mais rápida de buscar os dados (usando índices).
-
Storage Engine (O Diferencial): É o componente que
realmente grava os dados no disco.
- InnoDB (Padrão Moderno): Suporta transações (ACID) e chaves estrangeiras. É o que você deve usar em 99% dos casos.
- MyISAM (Antigo): Mais rápido para leitura, mas péssimo para escrita e não suporta transações. Caiu em desuso.
3. Por que usar MySQL?
Em um mundo com bancos NoSQL (MongoDB, Firebase), por que o bom e velho SQL relacional ainda domina?
- Integridade Relacional: Se você deletar um "Usuário", o MySQL pode automaticamente deletar todos os "Pedidos" dele (Cascade), mantendo os dados limpos.
- Padronização: Ele usa SQL (Structured Query Language). Se você aprender MySQL, já sabe 90% de PostgreSQL, SQL Server e SQLite.
- Escalabilidade: Gigantes como Facebook, Uber e Netflix usam MySQL modificado. Ele aguenta petabytes de dados se bem configurado.
- Stack LAMP: É a letra "M" da stack mais famosa da web (Linux, Apache, MySQL, PHP/Python).
4. Prática: 5 Exemplos Essenciais
Vamos simular a criação de um sistema de E-commerce para ver o SQL em ação.
Exemplo 1: Criando a Fundação (Banco e Tabela)
Primeiro, criamos o banco e a tabela de produtos, definindo tipos de dados rigorosos.
-- 1. Criar o Banco
CREATE DATABASE ecommerce_db;
USE ecommerce_db;
-- 2. Criar a Tabela
CREATE TABLE produtos (
id INT AUTO_INCREMENT PRIMARY KEY, -- Identidade única
nome VARCHAR(100) NOT NULL, -- Texto até 100 chars
preco DECIMAL(10, 2) NOT NULL, -- Dinheiro (10 dígitos, 2 decimais)
estoque INT DEFAULT 0, -- Inteiro, começa com 0
criado_em TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Exemplo 2: Povoando os Dados (Insert)
Vamos inserir produtos. Note que não precisamos passar o
id (é automático) nem a data (é automática).
INSERT INTO produtos (nome, preco, estoque)
VALUES
('Notebook Gamer', 4500.00, 10),
('Mouse Sem Fio', 50.50, 100),
('Teclado Mecânico', 250.00, 50),
('Monitor 4K', 1200.00, 5);
Exemplo 3: A Inteligência da Busca (Select & Filters)
O poder do SQL está em fazer perguntas complexas aos dados.
-- Pergunta: "Quais produtos custam mais de 100 reais e têm estoque?"
SELECT nome, preco
FROM produtos
WHERE preco > 100 AND estoque > 0
ORDER BY preco DESC; -- Ordenado do mais caro para o mais barato
Exemplo 4: Atualização Segura (Update)
Vamos aplicar um desconto de 10% em todos os mouses.
Cuidado: Sempre use WHERE no UPDATE. Sem
ele, você altera a tabela inteira!
UPDATE produtos
SET preco = preco * 0.90
WHERE nome LIKE '%Mouse%';
Exemplo 5: Transações (O Poder do ACID)
Imagine que você está vendendo o último monitor. Precisamos garantir que o estoque baixe e o pedido seja gerado simultaneamente.
START TRANSACTION;
-- Passo 1: Diminuir estoque
UPDATE produtos SET estoque = estoque - 1 WHERE id = 4;
-- Passo 2: Registrar venda (imaginando uma tabela de vendas)
INSERT INTO vendas (produto_id, valor) VALUES (4, 1200.00);
-- Se tudo deu certo, salvamos permanentemente
COMMIT;
-- Se algo deu errado, usaríamos ROLLBACK; para desfazer tudo.
Apêndice: Referência Rápida de Comandos
Use as tabelas abaixo como sua "cola" diária. Elas cobrem 95% do que você usará no trabalho.
Comandos SQL e Suas Funções
| Comando SQL | O que o comando faz |
|---|---|
| SELECT | Seleciona dados de uma ou mais tabelas |
| INSERT INTO | Insere novos dados em uma tabela |
| UPDATE | Atualiza dados existentes em uma tabela |
| DELETE | Remove dados de uma tabela |
| CREATE TABLE | Cria uma nova tabela no banco de dados |
| ALTER TABLE | Modifica uma tabela existente |
| DROP TABLE | Remove uma tabela do banco de dados |
| CREATE DATABASE | Cria um novo banco de dados |
| DROP DATABASE | Exclui um banco de dados |
| USE | Seleciona o banco de dados que será utilizado |
| WHERE | Filtra os registros com base em uma condição |
| ORDER BY | Ordena os resultados por uma ou mais colunas |
| GROUP BY | Agrupa os resultados com base em colunas |
| HAVING | Filtra grupos de resultados após o GROUP BY |
| JOIN | Combina registros de duas ou mais tabelas |
| INNER JOIN | Retorna registros com correspondência em ambas as tabelas |
| LEFT JOIN | Todos da esquerda e correspondentes da direita |
| RIGHT JOIN | Todos da direita e correspondentes da esquerda |
| FULL JOIN | Todos os registros com correspondência em uma das tabelas |
| UNION | Combina o resultado de duas instruções SELECT |
| DISTINCT | Retorna apenas valores distintos |
| LIKE | Pesquisa por um padrão em uma coluna |
| IN | Verifica se um valor está em uma lista |
| BETWEEN | Verifica se está dentro de um intervalo |
| IS NULL | Verifica se o valor é nulo |
| AS | Define um apelido para tabela ou coluna |
| LIMIT | Define o número máximo de registros retornados |
| OFFSET | Define o ponto inicial dos registros retornados |
| DEFAULT | Define valor padrão para coluna |
| PRIMARY KEY | Define uma chave primária |
| FOREIGN KEY | Define uma chave estrangeira |
| AUTO_INCREMENT | Valor auto incrementado automaticamente |
| NOT NULL | Impede que a coluna tenha valores nulos |
| CHECK | Impõe uma condição de validação |
| INDEX | Cria um índice para performance |
| VIEW | Cria uma visualização (consulta salva) |
| TRUNCATE TABLE | Remove todos os registros da tabela |
| RENAME TABLE | Renomeia uma tabela existente |
| GRANT | Concede permissões a usuários |
| REVOKE | Remove permissões de usuários |
Exemplos Práticos de Sintaxe
| Comando SQL | Exemplo Prático |
|---|---|
| SELECT | SELECT * FROM funcionarios; |
| INSERT INTO | INSERT INTO funcionarios (nome, cargo) VALUES ('Ana', 'Gerente'); |
| UPDATE | UPDATE funcionarios SET cargo = 'Diretora' WHERE nome = 'Ana'; |
| DELETE | DELETE FROM funcionarios WHERE nome = 'Ana'; |
| CREATE TABLE | CREATE TABLE funcionarios (id INT PRIMARY KEY, nome VARCHAR(100)); |
| ALTER TABLE | ALTER TABLE funcionarios ADD COLUMN salario DECIMAL(10,2); |
| DROP TABLE | DROP TABLE funcionarios; |
| CREATE DATABASE | CREATE DATABASE empresa; |
| DROP DATABASE | DROP DATABASE empresa; |
| USE | USE empresa; |
| WHERE | SELECT * FROM funcionarios WHERE cargo = 'Analista'; |
| ORDER BY | SELECT * FROM funcionarios ORDER BY nome ASC; |
| GROUP BY | SELECT cargo, COUNT(*) FROM funcionarios GROUP BY cargo; |
| HAVING | SELECT cargo, COUNT(*) FROM funcionarios GROUP BY cargo HAVING COUNT(*) > 2; |
| JOIN | SELECT * FROM funcionarios JOIN departamentos ON funcionarios.depto_id = departamentos.id; |
| INNER JOIN | SELECT * FROM funcionarios INNER JOIN departamentos ON funcionarios.depto_id = departamentos.id; |
| LEFT JOIN | SELECT * FROM funcionarios LEFT JOIN departamentos ON funcionarios.depto_id = departamentos.id; |
| RIGHT JOIN | SELECT * FROM funcionarios RIGHT JOIN departamentos ON funcionarios.depto_id = departamentos.id; |
| FULL JOIN | SELECT * FROM funcionarios FULL OUTER JOIN departamentos ON funcionarios.depto_id = departamentos.id; |
| UNION | SELECT nome FROM funcionarios UNION SELECT nome FROM clientes; |
| DISTINCT | SELECT DISTINCT cargo FROM funcionarios; |
| LIKE | SELECT * FROM funcionarios WHERE nome LIKE 'A%'; |
| IN | SELECT * FROM funcionarios WHERE cargo IN ('Gerente', 'Diretor'); |
| BETWEEN | SELECT * FROM funcionarios WHERE salario BETWEEN 2000 AND 5000; |
| IS NULL | SELECT * FROM funcionarios WHERE data_saida IS NULL; |
| AS | SELECT nome AS 'Funcionário', cargo AS 'Cargo Atual' FROM funcionarios; |
| LIMIT | SELECT * FROM funcionarios LIMIT 5; |
| OFFSET | SELECT * FROM funcionarios LIMIT 5 OFFSET 10; |
| DEFAULT | CREATE TABLE produtos (id INT, nome VARCHAR(50), status VARCHAR(20) DEFAULT 'ativo'); |
| PRIMARY KEY | CREATE TABLE funcionarios (id INT PRIMARY KEY, nome VARCHAR(100)); |
| FOREIGN KEY | ALTER TABLE funcionarios ADD CONSTRAINT fk_depto FOREIGN KEY (depto_id) REFERENCES departamentos(id); |
| AUTO_INCREMENT | id INT AUTO_INCREMENT PRIMARY KEY |
| NOT NULL | nome VARCHAR(100) NOT NULL |
| CHECK | salario DECIMAL(10,2) CHECK (salario > 0) |
| INDEX | CREATE INDEX idx_nome ON funcionarios(nome); |
| VIEW | CREATE VIEW analistas AS SELECT * FROM funcionarios WHERE cargo = 'Analista'; |
| TRUNCATE TABLE | TRUNCATE TABLE funcionarios; |
| RENAME TABLE | RENAME TABLE funcionarios TO colaboradores; |
| GRANT | GRANT SELECT ON empresa.funcionarios TO 'usuario'; |
| REVOKE | REVOKE SELECT ON empresa.funcionarios FROM 'usuario'; |
Conclusão
O MySQL é uma ferramenta indispensável. Saber escrever queries SQL otimizadas é o que diferencia um programador júnior de um sênior.
Próximo Passo: Agora que você entende o SQL puro, estude como conectar o MySQL ao seu código usando um ORM (como Sequelize para Node.js, Hibernate para Java ou Eloquent para PHP/Laravel). O ORM vai escrever o SQL chato para você, mas agora você saberá o que acontece por baixo dos panos. 🐬
